package com.fy.springmvc2.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@CrossOrigin //实现跨域，打破同源策略
public class FileController {
    @RequestMapping("/upload")
    public String upload(MultipartFile upload, String name, Model model, HttpServletRequest request) throws IOException {
        // name用户名字，upload上传的文件
        //需求 上传到web的upload文件夹中(指定路径) 文件名使用原始的文件名(文件名)

        //1 获取web服务器中部署项在磁盘上的真实路径
        String realPath = request.getServletContext().getRealPath("/");
        System.out.println(realPath);
        //2 在上述路径中 创建upload文件夹
        File uploadDir = new File(realPath, "upload");
        if (!uploadDir.exists()) {
            //如果upload目录不存在 就创建一个目录
            uploadDir.mkdirs();
        }
        //3 获取上传的文件的名字
       // String filename = upload.getOriginalFilename();

        //3.获取上传的文件名 有可能存在：1.文件名重复 2.文件名过长
        String filename=reName(upload.getOriginalFilename());

        /** 4 【核心方法】IO流操作进行文件复制 指定要存放的位置和文件名称 */
        upload.transferTo(new File(uploadDir, filename));
        model.addAttribute("msg", "文件上传成功");//生成路径=>target/springmvc2-1.0-SNAPSHOT/upload

        //5 在页面上显示上传文件目录中都有哪些文件
        String[] fileNames = uploadDir.list();
        model.addAttribute("fileNames", fileNames);
        return "welcome";
    }


    // 多文件上传 uploadFiles接收的多个文件
    @RequestMapping("/upload2")
    public String upload2(MultipartFile[] uploadFiles, String name, Model model, HttpServletRequest request) throws IOException {
        // 1、获取web服务器中部署项目在磁盘上的真实路径
        String realPath = request.getServletContext().getRealPath("/");
        System.out.println(realPath);
        // 2、在上述路径下创建一个upload文件夹
        File uploadDir = new File(realPath, "upload");
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        for (MultipartFile upload : uploadFiles) {
            // 3、获取上传文件的名字
            String filename = upload.getOriginalFilename();
            // 3.1 如果只允许用户上传图片,不能上传其他文件   xxx.jpg  xxx.png  xxx.bmp xxx.gif
            // 获取文件后缀名
            String suffix = filename.substring(filename.indexOf("."));
            if (suffix.equalsIgnoreCase(".jpg") || suffix.equalsIgnoreCase(".png")
                    || suffix.equalsIgnoreCase(".bmp") || suffix.equalsIgnoreCase(".gif")) {
                // 3.2 重命名文件
                String uuid = UUID.randomUUID().toString();
                uuid = uuid.replace("-", "") + suffix;
                // 4、IO流操作进行文件复制
                upload.transferTo(new File(uploadDir, uuid));
                model.addAttribute("msg", "文件上传成功!");
                // 5、在页面上显示一下上传文件目录中都有哪些文件
                String[] fileNames = uploadDir.list();
                model.addAttribute("fileNames", fileNames);
            } else {
                // 上传的不是图片
                model.addAttribute("msg", "上传的不是图片!");
                return "upload";
            }
        }
        return "welcome";
    }



    //文件下载的处理器
    @RequestMapping("/download")
    public void download(String filename, HttpServletResponse response, HttpServletRequest request) throws IOException {
       try {
           System.out.println("要下载的文件名是：" + filename);
           response.setHeader("Content-disposition", "attachment;filename=" + filename);
           //获取下载的文件所在目录的真实地址
           String realPath = request.getServletContext().getRealPath(File.separator+"upload");
           // 构造要下载的文件对象
           File file = new File(realPath, filename);
           // 读取文件内容到字节数组中
           byte[] bytes = FileUtils.readFileToByteArray(file);
           ServletOutputStream outputStream = response.getOutputStream();
           outputStream.write(bytes);
           outputStream.close();
       }catch (Exception e){
           e.printStackTrace();
       }
    }



    /**
     * 实现上传的文件名长度截取(<=30)和重命名 保证唯一性*/
    private String reName(String fn){
        //1.验证是否长度超出30
        if(fn.length()>30){
            //截取长度，一定要从后往前。要保留文件的后缀名
            fn=fn.substring(fn.length()-30);
        }
        //2.重命名 保证唯一性 UUID(生成32位不重复的字符串)
        return UUID.randomUUID().toString().replace("-","")+"_"+fn;
        //时间戳 豪秒
        //return System.currentTimeMillis()+"_"+fn;
    }

}
